package cn.com.guage.dtm.metadata.controller;

import java.sql.SQLException;
import java.util.List;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import cn.com.guage.dtm.common.annotation.Log;
import cn.com.guage.dtm.common.enums.BusinessType;
import cn.com.guage.dtm.common.exception.BusinessException;
import cn.com.guage.dtm.metadata.domain.MdReverseEngineering;
import cn.com.guage.dtm.metadata.domain.MdSys;
import cn.com.guage.dtm.metadata.domain.MdTable;
import cn.com.guage.dtm.metadata.service.IMdReverseEngineeringService;
import cn.com.guage.dtm.metadata.service.IMdSysService;
import cn.com.guage.dtm.metadata.service.IMdTableService;
import cn.com.guage.dtm.metadata.service.impl.MdReverseEngineeringServiceImpl;
import cn.com.guage.dtm.utils.AESDecrypt;
import cn.com.guage.dtm.utils.AESEncrypt;
import cn.com.guage.dtm.common.core.controller.BaseController;
import cn.com.guage.dtm.common.core.domain.AjaxResult;
import cn.com.guage.dtm.common.utils.poi.ExcelUtil;
import cn.com.guage.dtm.common.core.page.TableDataInfo;

/**
 * 逆向工程Controller
 * 
 * @author liujun
 * @date 2021-06-25
 */
@Controller
@RequestMapping("/metadata/engineering")
public class MdReverseEngineeringController extends BaseController
{
	private static final Logger log = LoggerFactory.getLogger(MdReverseEngineeringController.class);

    private String prefix = "metadata/engineering";

    @Autowired
    private IMdReverseEngineeringService mdReverseEngineeringService;
    
    @Autowired
    private IMdSysService mdSysService;
    
    @Autowired
    private IMdTableService iMdTableService;

    @RequiresPermissions("metadata:engineering:view")
    @GetMapping()
    public String engineering(ModelMap mmap)
    {
    	MdSys mdSys=new MdSys();
    	List<MdSys> mdSysList = mdSysService.selectMdSysList(mdSys);
    	mmap.put("mdSysList", mdSysList);
        return prefix + "/engineering";
    }

    /**
     * 查询逆向工程列表
     */
    @RequiresPermissions("metadata:engineering:list")
    @PostMapping("/list")
    @ResponseBody
    public TableDataInfo list(MdReverseEngineering mdReverseEngineering)
    {
        startPage();
        List<MdReverseEngineering> list = mdReverseEngineeringService.selectMdReverseEngineeringList(mdReverseEngineering);
        return getDataTable(list);
    }

    /**
     * 导出逆向工程列表
     */
    @RequiresPermissions("metadata:engineering:export")
    @Log(title = "逆向工程", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    @ResponseBody
    public AjaxResult export(MdReverseEngineering mdReverseEngineering)
    {
        List<MdReverseEngineering> list = mdReverseEngineeringService.selectMdReverseEngineeringList(mdReverseEngineering);
        ExcelUtil<MdReverseEngineering> util = new ExcelUtil<MdReverseEngineering>(MdReverseEngineering.class);
        return util.exportExcel(list, "逆向工程数据");
    }

    /**
     * 新增逆向工程
     */
    @GetMapping("/add")
    public String add(ModelMap mmap)
    {
    	MdSys mdSys=new MdSys();
    	List<MdSys> mdSysList = mdSysService.selectMdSysList(mdSys);
        mmap.put("mdSysList", mdSysList);
        return prefix + "/add";
    }

    /**
     * 新增保存逆向工程
     */
    @RequiresPermissions("metadata:engineering:add")
    @Log(title = "逆向工程", businessType = BusinessType.INSERT)
    @PostMapping("/add")
    @ResponseBody
    public AjaxResult addSave(MdReverseEngineering mdReverseEngineering)
    {
        return toAjax(mdReverseEngineeringService.insertMdReverseEngineering(mdReverseEngineering));
    }

    /**
     * 修改逆向工程
     */
    @GetMapping("/edit/{reverseId}")
    public String edit(@PathVariable("reverseId") Long reverseId, ModelMap mmap)
    {
        MdReverseEngineering mdReverseEngineering = mdReverseEngineeringService.selectMdReverseEngineeringById(reverseId);
        AESDecrypt decry=new AESDecrypt(AESEncrypt.ENCRYPASSWORD);
    	String decryPassword=decry.decryptForCBC(mdReverseEngineering.getJdbcPassword());
    	mdReverseEngineering.setJdbcPassword(decryPassword);
    	logger.info("decryPassword:"+decryPassword);
        mmap.put("mdReverseEngineering", mdReverseEngineering);
        
        MdSys mdSys=new MdSys();
        List<MdSys> mdSysList = mdSysService.selectMdSysList(mdSys);
        mmap.put("mdSysList", mdSysList);
        return prefix + "/edit";
    }

    /**
     * 修改保存逆向工程
     */
    @RequiresPermissions("metadata:engineering:edit")
    @Log(title = "逆向工程", businessType = BusinessType.UPDATE)
    @PostMapping("/edit")
    @ResponseBody
    public AjaxResult editSave(MdReverseEngineering mdReverseEngineering)
    {
    	AESEncrypt encry=new AESEncrypt(AESEncrypt.ENCRYPASSWORD);
    	String encryPassword=encry.encryptForCBC(mdReverseEngineering.getJdbcPassword());
    	mdReverseEngineering.setJdbcPassword(encryPassword);
        return toAjax(mdReverseEngineeringService.updateMdReverseEngineering(mdReverseEngineering));
    }

    /**
     * 删除逆向工程
     */
    @RequiresPermissions("metadata:engineering:remove")
    @Log(title = "逆向工程", businessType = BusinessType.DELETE)
    @PostMapping( "/remove")
    @ResponseBody
    public AjaxResult remove(String ids)
    {
        return toAjax(mdReverseEngineeringService.deleteMdReverseEngineeringByIds(ids));
    }
    
    
    
    /**
     * 逆向工程提取表、字段、索引数据
     */
    @RequiresPermissions("metadata:engineering:extract")
//    @Log(title = "逆向工程", businessType = BusinessType.DELETE)
    @GetMapping( "/extract/{reverseId}")
    @ResponseBody
    public AjaxResult extract(@PathVariable("reverseId") Long reverseId)
	{
		int rowNumber = 0;
		MdTable mdTableCheck = new MdTable();
		MdReverseEngineering mdReverseEngineering = mdReverseEngineeringService
				.selectMdReverseEngineeringById(reverseId);
		mdTableCheck.setSysId(mdReverseEngineering.getSysId());
		int existTableNumber = iMdTableService.selectMdTableList(mdTableCheck).size();
		log.warn("exist metadata table number is: {}.", existTableNumber);
		if (existTableNumber > 0)
			return AjaxResult.error("存在已有元数据，请清除后重试。");
		try {
			rowNumber = mdReverseEngineeringService.extractDbMetadata(mdReverseEngineering,true);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			return AjaxResult.error("清除元数据异常。");
		}
		log.debug("table find:{}", rowNumber);
		
//		log.debug("dataTypeList find:{}", MdReverseEngineeringServiceImpl.dataTypeList.size());
//		MdReverseEngineeringServiceImpl.dataTypeList.stream().forEach(t->System.out.println(t));
		
//    	return toAjax(rowNumber);//只用>0判断成功或者失败，不返回数字。
		return AjaxResult.success("元数据抽取成功。");
	}
    
    /**
     * 清除已有的元数据信息，包括表、字段与索引
     * @param reverseId
     * @return
     */
    @RequiresPermissions("metadata:engineering:extract")
    @GetMapping( "/clear/{reverseId}")
    @ResponseBody
    public AjaxResult clear(@PathVariable("reverseId") Long reverseId)
    {
    	try {
    		mdReverseEngineeringService.clearDbMetadataById(reverseId);
		} catch (Exception e) {
			// TODO Auto-generated catch block
//			e.printStackTrace();
			AjaxResult.error(e.getMessage());
		}
    	return AjaxResult.success();
    }
    
    @PostMapping("/testdb")
    @ResponseBody
    public AjaxResult testdb(MdReverseEngineering mdReverseEngineering)
    {
    	try {
			int returnValue = mdReverseEngineeringService.extractDbMetadata(mdReverseEngineering,false);
			log.debug("testdb return:{}", returnValue);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			return AjaxResult.error("数据库连接失败。");
		}
    	return AjaxResult.success("数据库连接成功。");
    }
}
